package sw6.bmi;

import java.text.DecimalFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import sw6.bmi.profile.EditImageActivity;
import sw6.bmi.profile.Image;
import sw6.girafAppKit.GirafActivity;
import sw6.lib.Settings;
import sw6.lib.types.Interval;
import sw6.lib.user.Profile;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.TextView;


public class MainActivity extends GirafActivity {

	/*
	 * Statics used to look up / identify settings from sw6.admin
	 */
	private static final String sSETTING_BOOLEAN_IS_FIRST_RUN 	= "isFirstRun";
	private static final String sSETTING_INT_LAST_EXEC_VERSION	= "lastExecutedVersion";
	private static final String sSETTING_DOUBLE_HEIGHT 			= "height";
	private static final String sSETTING_DOUBLE_WEIGHT 			= "weight";
	private static final String sSETTING_INTERVAL_NORMAL_BMI 	= "normalBmi";
	private static final String sSETTING_BOOLEAN_SHOW_WEIGHT 	= "showWeight";
	public static final String sSETTING_OBJECT_IMAGE 			= "image";
	private static final int sCALLBACK_EDIT_IMAGE_ACT			= 1000;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}
	
	@Override
	public void onResume() {
		super.onResume();
		initializeActivity();
	}
	
	private void initializeActivity() {
		
		// Set the intent to be called when user is going into admin mode
		Intent adminIntent = new Intent();
		adminIntent.setComponent(new ComponentName("sw6.admin", "sw6.admin.MainActivity"));
		adminIntent.putExtra("packageName", "sw6.bmi");
		setParentIntent(adminIntent);
		
		boolean isFirstRun = Settings.getBoolean(this, sSETTING_BOOLEAN_IS_FIRST_RUN);
		int lastExecutedVersion = Settings.getInteger(this, sSETTING_INT_LAST_EXEC_VERSION);
		
		int currentVersion = lastExecutedVersion;
		try {
			currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
		} catch (NameNotFoundException e) {
			// something went wrong
		}
		
		// Check for first run and package upgrade
		if(isFirstRun || (currentVersion > lastExecutedVersion)) {
			if(isFirstRun) {
				// Set interval defaults
				Settings.setStdObject(this, sSETTING_INTERVAL_NORMAL_BMI, new Interval(18, 25, 18, 25));
			}
			
			// Start camera activity to set image for the first time
			Intent intent = new Intent(this, EditImageActivity.class);
			startActivityForResult(intent, sCALLBACK_EDIT_IMAGE_ACT);
			
			// Set last executed version
			Settings.setInteger(this, sSETTING_INT_LAST_EXEC_VERSION, currentVersion);
		} else {

			// Get app settings from sw6.admin 
			double height = Settings.getDouble(this, sSETTING_DOUBLE_HEIGHT);
			double weight = Settings.getDouble(this, sSETTING_DOUBLE_WEIGHT);
			Interval normalBmi = Settings.getStdObject(this, sSETTING_INTERVAL_NORMAL_BMI, Interval.class);
			Profile userProfile = Settings.getUserProfile(this);

			// Compute BMI
			double bmi = computeBmi(height, weight);
			
			// Set colored header
			TextView tv = (TextView) findViewById(R.id.textViewAppName);
			SpannableStringBuilder text = new SpannableStringBuilder(getString(R.string.app_name) + ", v." + currentVersion);
			text.setSpan(new ForegroundColorSpan(Color.GREEN), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			text.setSpan(new ForegroundColorSpan(Color.YELLOW), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			text.setSpan(new ForegroundColorSpan(Color.RED), 4, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			text.setSpan(new ForegroundColorSpan(Color.CYAN), 5, 6, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			text.setSpan(new ForegroundColorSpan(Color.MAGENTA), 6, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			text.setSpan(new ForegroundColorSpan(Color.GREEN), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			tv.setText(text);
			tv.setGravity(Gravity.CENTER_HORIZONTAL);
			
			// Set hello, welcome msg
			TextView textViewWelcome = (TextView) findViewById(R.id.textViewWelcome);
			textViewWelcome.setText("Hello, " + userProfile.getName() + " ;)");

			// Set birthday header
			Calendar birthday = userProfile.getBirthDay();
			long age_milliseconds = Calendar.getInstance().getTimeInMillis() - birthday.getTimeInMillis();
			Calendar age_cal = Calendar.getInstance();
			age_cal.setTimeInMillis(age_milliseconds);
			int age = age_cal.getTime().getYear()-70;
			Format formatter = new SimpleDateFormat("dd-MMM-yyyy");
			TextView textViewAge = (TextView) findViewById(R.id.textViewAge);
			textViewAge.setText(formatter.format(birthday.getTime()) + " " + "(" + age + "years)");
			
			// Set height, weight, BMI header
			DecimalFormat df = new DecimalFormat("#.#");
			TextView textViewBmiValue = (TextView) findViewById(R.id.textViewBmiValue);
			textViewBmiValue.setText("BMI: " + df.format(bmi));

			// Show height if allowed to
			boolean allowedToShowWeight = Settings.getBoolean(this, sSETTING_BOOLEAN_SHOW_WEIGHT);
			if(allowedToShowWeight) {
				TextView textViewWeight = (TextView) findViewById(R.id.textViewWeight);
				textViewWeight.setText(weight + "kg");
			}

			TextView textViewHeight = (TextView) findViewById(R.id.textViewHeight);
			textViewHeight.setText(Settings.getDouble(this, sSETTING_DOUBLE_HEIGHT) + "cm");
			
			// Show BMI evaluation with color
			TextView textViewBmiEvaluation = (TextView) findViewById(R.id.textViewBmiEvaluation);
			evaluateBmi(bmi, normalBmi, textViewBmiEvaluation);
			
			// Load image from the DB in sw6.admin
			Image image = Settings.getObject(this, sSETTING_OBJECT_IMAGE, Image.class);
			ImageView imageViewProfileImg = (ImageView) findViewById(R.id.imageViewProfileImg);
			imageViewProfileImg.setImageBitmap(image.getImageBitmap());
			imageViewProfileImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
			imageViewProfileImg.setAdjustViewBounds(true);
		}   
	}
	
	/**
	 * Computes the BMI
	 * @param height in centimeters (cm)
	 * @param weight in kilograms (kg)
	 * @return the BMI
	 */
	private double computeBmi(double height, double weight) {
		
		// convert from cm to m
		height = height / 100;
		
		// prevent divide by zero
		if(height == 0) {
			return 0.0;
		} else {
			return weight/(height*height);
		}
	}

	private void evaluateBmi(double bmi, Interval normalBmi, TextView textView) {
		
		String category;
		int color;
		
		if(normalBmi.contains((int) bmi)) {
			category = "You have a NORMAL weight :)";
			color = Color.GREEN;
		} else if(bmi < normalBmi.getFrom()) {
			category = "You are UNDERWEIGHT :(";
			color = Color.RED;
		} else {
			category = "You are OVERWEIGHT :(";
			color = Color.RED;
		}
		
		SpannableStringBuilder text = new SpannableStringBuilder(category);
		text.setSpan(new ForegroundColorSpan(color), 0, category.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		textView.setText(text);
		textView.setGravity(Gravity.CENTER_HORIZONTAL);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if(requestCode == sCALLBACK_EDIT_IMAGE_ACT) {
			if (resultCode == EditImageActivity.sRESULT_NEW_IMG) {
				Settings.setBoolean(this, sSETTING_BOOLEAN_IS_FIRST_RUN, false);
				initializeActivity();
			} else {
				// User did not take a new image, so quit!
				finish();
			}
		}
	}
}